﻿//Copyright 2008 Kristian Gundry And Rune Juhl-Petersen
//This file is part of Plain.

//Plain is free software: you can redistribute it and/or modify
//it under the terms of the GNU Lesser General Public License as published by
//the Free Software Foundation, either version 3 of the License, or
//any later version.

//Plain is distributed in the hope that it will be useful,
//but WITHOUT ANY WARRANTY; without even the implied warranty of
//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//GNU Lesser General Public License for more details.

//You should have received a copy of the GNU Lesser General Public License
//along with Plain.  If not, see <http://www.gnu.org/licenses/>.
using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;
using Plain.Mapping;

namespace Plain.Validation
{
    /// <summary>
    /// This is a helper class to provide validation of domain objects through <see cref="IValidationAttribute"/> attributes
    /// </summary>
    public static class Validator {
        /// <summary>
        /// Validates an object against the <see cref="IValidationAttribute"/>'s decorading the class.
        /// </summary>
        /// <param name="o">object to validate</param>
        /// <param name="result">A list used to gather all the validations that fail</param>
        /// <returns>True if no validation fails else false</returns>
        public static bool Validate(this object o,IList<string> result) {
            bool valid = true;
            foreach(PropertyInfo prop in o.GetType().GetProperties()){
                if (!Validate( o,prop,result)) {
                    if (result != null){
                        valid = false;
                    } else {
                        return false;
                    }
                }
            }
            return valid;
        }
        /// <summary>
        /// Validates a single property
        /// </summary>
        /// <param name="entity"></param>
        /// <param name="prop"></param>
        /// <param name="result"></param>
        /// <returns></returns>
        public static bool Validate(object entity,PropertyInfo prop,IList<string> result) {
            bool valid = true;
            foreach (Attribute att in prop.GetCustomAttributes(true)){
                if (att is IValidationAttribute) {
                    IValidationAttribute val = (IValidationAttribute)att;
                    if (!val.Validate(entity, prop.GetValue(entity, null))){
                        if (result != null){
                            result.Add(ValidationMapping.GetMessage(val,prop));
                            valid = false;
                        } else{
                            return false;
                        }
                    }
                }
            }
            return valid;
        }

        /// <summary>
        /// Validates the object. How validation is exceuted is controlled by marking the class with <see cref="IValidationAttribute"/> attributes.
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public static bool Validate(this object entity) {
            return Validate(entity,null);
        }

        ///Commented out for 3.5
       
      
    }
   
}
